package com.seckillpro.seckill_pro.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seckillpro.seckill_pro.exception.GlobalException;
import com.seckillpro.seckill_pro.mapper.TOrderMapper;
import com.seckillpro.seckill_pro.pojo.TOrder;
import com.seckillpro.seckill_pro.pojo.TSecKillGoods;
import com.seckillpro.seckill_pro.pojo.TSecKillOrder;
import com.seckillpro.seckill_pro.pojo.TUser;
import com.seckillpro.seckill_pro.service.ITGoodsService;
import com.seckillpro.seckill_pro.service.ITOrderService;
import com.seckillpro.seckill_pro.service.ITSecKillGoodsService;
import com.seckillpro.seckill_pro.service.ITSecKillOrderService;
import com.seckillpro.seckill_pro.utils.MD5Util;
import com.seckillpro.seckill_pro.utils.UUIDUtil;
import com.seckillpro.seckill_pro.vo.GoodsVo;
import com.seckillpro.seckill_pro.vo.OrderDetailVo;
import com.seckillpro.seckill_pro.vo.RespBeanEnum;
import lombok.extern.slf4j.Slf4j;
import lombok.extern.slf4j.XSlf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.StringUtils;

import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lyx
 * @since 2021-03-05
 */

@Transactional
@Service
@Slf4j
public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> implements ITOrderService {

    @Autowired
    private ITSecKillGoodsService secKillGoodsService;

    @Autowired
    private TOrderMapper orderMapper;

    @Autowired
    private ITSecKillOrderService seckillOrderService;

    @Autowired
    private ITGoodsService goodsService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 秒杀商品
     *
     * @param user
     * @param goods
     * @return
     */
    @Override
    public TOrder secKill(TUser user, GoodsVo goods) {

        ValueOperations valueOperations = redisTemplate.opsForValue();
        //秒杀商品表库存减一
        TSecKillGoods secKillGoods =
                secKillGoodsService.getOne(new QueryWrapper<TSecKillGoods>().eq("good_id", goods.getId()));
        log.info(secKillGoods.toString());
        secKillGoods.setStockCount(secKillGoods.getStockCount() - 1);
        log.info(secKillGoods.getStockCount().toString());
        //当库存大于0，id等于商品id的时候，将当前库存数量存入数据库
        secKillGoodsService.update(new UpdateWrapper<TSecKillGoods>()
                .setSql("stock_count = stock_count-1").eq("good_id", goods.getId()).gt("stock_count", 0));

        if (secKillGoods.getStockCount() < 1) {
            //判断是否还有库存
            valueOperations.set("isStockEmpty:" + goods.getId(), "0");
            return null;
        }
        //生成订单
        TOrder order = new TOrder();
        order.setUserId(user.getId());
        order.setGoodId(goods.getId());
        order.setDeliveryAddrId(0L);
        order.setGoodName(goods.getGoodName());
        order.setGoodCount(1);
        order.setGoodPrice(secKillGoods.getSecKillPrice());
        order.setOrderChannel(1);
        order.setStatus(0);
        order.setCreateDate(new Date());
        orderMapper.insert(order);

        //生成秒杀订单
        TSecKillOrder secKillOrder = new TSecKillOrder();
        secKillOrder.setUserId(user.getId());
        secKillOrder.setOrderId(order.getId());
        secKillOrder.setGoodId(goods.getId());
        seckillOrderService.save(secKillOrder);

        valueOperations.set("order:" + user.getId() + ":" + goods.getId(), secKillOrder);
        return order;
    }

    /**
     * 功能描述：订单详情
     *
     * @param orderId 订单id
     * @return 订单详情返回对象
     */
    @Override
    public OrderDetailVo detail(Long orderId) {

        if (ObjectUtil.isEmpty(orderId)) {
            throw new GlobalException(RespBeanEnum.ORDER_NOT_EXIST);
        }

        TOrder order = orderMapper.selectById(orderId);
        log.info(orderId.toString());
        GoodsVo goodsVo = goodsService.findGoodsVoByGoodId(order.getGoodId());

        OrderDetailVo detailVo = new OrderDetailVo();
        detailVo.setOrder(order);
        detailVo.setGoodsVo(goodsVo);
        log.info(detailVo.toString());

        return detailVo;
    }

    /**
     * 创建path
     *
     * @param user
     * @param goodId
     * @return
     */
    @Override
    public String createPath(TUser user, Long goodId) {
        String str = MD5Util.md5(UUIDUtil.uuid() + "123456");
        redisTemplate.opsForValue().set("secKillPath:" + user.getId() + ":" + goodId, str, 60, TimeUnit.
                SECONDS);
        return str;
    }


    /**
     * 校验path的合法性
     *
     * @param user
     * @param goodId
     * @return
     */
    @Override
    public boolean checkPath(TUser user, Long goodId, String path) {

        System.out.println(path);
        if (ObjectUtil.isEmpty(user) || null == goodId || ObjectUtil.isEmpty(path)) {
            return false;
        }
        String redisPath = (String) redisTemplate.opsForValue().get("secKillPath:" + user.getId() + ":" + goodId);

        return path.equals(redisPath);
    }

    /**
     * 验证码校验
     *
     * @param user
     * @param goodId
     * @param captcha
     * @return
     */
    @Override
    public boolean checkCaptcha(TUser user, Long goodId, String captcha) {
        if (ObjectUtil.isEmpty(user) || goodId < 0 || StrUtil.isEmpty(captcha)) {
            return false;
        }

        String redisCaptcha = (String) redisTemplate.opsForValue().get("captcha:" + user.getId() + ":" + goodId);

            return captcha.equals(redisCaptcha);


    }
}
